/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2024-2024. All rights reserved.
 *
 */

import { FileSet, TaskInputValue } from '@ohos/hvigor';
import fse from 'fs-extra';
import path from 'path';

import { BuildDirConst } from '../../const/build-directory-const.js';
import { CommonConst } from '../../const/common-const.js';
import { ApiVersion } from '../../const/sdk-const.js';
import { SignTypeEnum } from '../../enum/sign-type-enum.js';
import { InjectUtil } from '../../utils/inject-util.js';
import { execOhpmPack } from '../../utils/npm-utils.js';
import { BaseSign } from '../base/base-sign.js';
import { TaskNames } from '../common/task-names.js';
import { TargetTaskService } from '../service/target-task-service.js';
import { SignModel } from '../sign/command-builder-impl/sign-model.js';
import { isSigned } from '../sign/sign-util.js';

/**
 * Sign&Package har
 *
 * @since 2024/05/11
 */
export class PackageSignHar extends BaseSign {
  protected readonly compiledRoot: string;
  protected readonly taskTmpRoot: string;
  protected readonly outputFile: string;
  protected readonly packageRoot: string;

  constructor(targetService: TargetTaskService) {
    super(targetService, TaskNames.CommonTask.PACKAGE_SIGN_HAR, SignTypeEnum.HAR);
    this.compiledRoot = this.getTaskTempDir(this.targetData, `${this.targetData.getTargetName()}@${TaskNames.Task.PACKAGE_HAR.name}`, false);
    this.taskTmpRoot = this.getTaskTempDir(this.targetData);
    this.packageRoot = path.resolve(this.taskTmpRoot, BuildDirConst.PACKAGE_HAP);
    const artifactName = this.targetData.getTargetOpt().output?.artifactName;
    const outputArtifactName = artifactName ? `${artifactName}` : `${this.moduleName}`;
    this.outputFile = path.resolve(this.pathInfo.getModuleBuildOutputPath(), `${outputArtifactName}-signed.har`);
  }

  protected beforeTask() {
    fse.emptyDirSync(this.taskTmpRoot);
    if (fse.existsSync(this.outputFile)) {
      fse.rmSync(this.outputFile);
    }
  }

  declareInputs(): Map<string, TaskInputValue> {
    const inputs = super.declareInputs();

    inputs.delete(CommonConst.ENABLE_SIGN_TASK);

    inputs
      .set('isDaemon', InjectUtil.isDaemon())
      .set('compileApiVersion', this.compileApiVersion)
      .set('compatibleApiVersion', this.compatibleApiVersion)
      .set('isSigned', isSigned(this.projectModel, true))
      .set('isHarmonyOS', this.targetService.getTargetData().isHarmonyOS());

    return inputs;
  }

  taskShouldDo(): boolean {
    return (
      InjectUtil.isDaemon() &&
      this.isOhpmProject &&
      isSigned(this.projectModel, true) &&
      this.compileApiVersion >= ApiVersion.API_VERSION_12 &&
      this.compatibleApiVersion >= ApiVersion.API_VERSION_12 &&
      this.targetService.getTargetData().isHarmonyOS() &&
      fse.existsSync(this.sdkInfo.getHosSignTool())
    );
  }

  declareInputFiles(): FileSet {
    return super.declareInputFiles().addEntry(this.compiledRoot, { isDirectory: true }).addEntry(this.taskTmpRoot, { isDirectory: true });
  }

  declareOutputFiles(): FileSet {
    const fileSet = super.declareOutputFiles();
    fileSet.addEntry(this.outputFile, { isDirectory: false });
    return fileSet;
  }

  protected async doTaskAction() {
    fse.copySync(this.compiledRoot, this.packageRoot);
    const signModel = new SignModel(this.signType, this.taskTmpRoot, '');
    await this.signUtil.sign(signModel, this.durationEvent);
    await execOhpmPack(this.taskTmpRoot, this.outputFile, this.durationEvent, false);
  }

  initTaskDepends() {
    // empty
  }
}
